package com.such.kit.stream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import com.such.kit.Logger;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @作者 SUCH
 * @日期 2017-2-20 上午10:49:24
 * @描述 通用的 IO 操作工具类
 */
public class StreamCommons {

	/**
	 * <p>方法名：binaryTransport</p>
	 * <p>描述：二进制方式传输流</p>
	 * @param in 输入流，即流的来源
	 * @param out 输出流，即流的去向
	 * @throws IOException
	 */
	public static void binaryTransport(InputStream in, OutputStream out) 
			throws IOException {
		binaryTransport(in, true, out, true);
	}

	/**
	 * <p>方法名：binaryTransport</p>
	 * <p>描述：二进制方式传输流</p>
	 * @param in 输入流，即流的来源
	 * @param closeIn 是否关闭输入流
	 * @param out 输出流，即流的去向
	 * @param closeOut 是否关闭输出流
	 * @throws IOException
	 */
	public static void binaryTransport(InputStream in, boolean closeIn, OutputStream out, boolean closeOut) 
			throws IOException {
		if (ValidateCommons.isNotEmpty(in) && ValidateCommons.isNotEmpty(out, false)) {
			BufferedInputStream bufIn = new BufferedInputStream(in);
			BufferedOutputStream bufOut = new BufferedOutputStream(out);
			try {
				byte[] byteBuffer = new byte[1024];
				int index = 0;
				while ((index = bufIn.read(byteBuffer)) != -1) {
					bufOut.write(byteBuffer, 0, index);
					bufOut.flush();
				}
			} finally {
				if (closeIn) {
					close(bufIn);
				}
				if (closeOut) {
					close(bufOut);
				}
			}
			
		}
	}

	/**
	 * <p>方法名：binaryReader</p>
	 * <p>描述：读取二进制流，并返字节数组</p>
	 * @param in 输入流，即流的来源
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] binaryReader(InputStream in) 
			throws IOException {
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
		if (ValidateCommons.isNotEmpty(in)) {
			BufferedInputStream bufIn = new BufferedInputStream(in);
			try {
				byte[] byteBuffer = new byte[1024];
				int index = 0;
				while ((index = bufIn.read(byteBuffer)) != -1) {
					byteOut.write(byteBuffer, 0, index);
					byteOut.flush();
				}
			} finally {
				close(bufIn);
				close(byteOut);
			}
			
		}
		return byteOut.toByteArray();
	}

	/**
	 * <p>方法名：textTransport</p>
	 * <p>描述：文本方式传输流</p>
	 * @param r 读入流
	 * @param w 写出流
	 * @throws Exception
	 */
	public static void textTransport(InputStreamReader r, OutputStreamWriter w) 
			throws IOException {
		textTransport(r, true, w, true);
	}

	/**
	 * <p>方法名：textTransport</p>
	 * <p>描述：文本方式传输流</p>
	 * @param r 读入流
	 * @param w 写出流
	 * @param closeWriter 是否关闭写出流
	 * @throws Exception
	 */
	public static void textTransport(InputStreamReader r, boolean closeReader, OutputStreamWriter w, boolean closeWriter) 
			throws IOException {
		if (ValidateCommons.isNotEmpty(r) && ValidateCommons.isNotEmpty(w)) {
			BufferedReader br = new BufferedReader(r);
			BufferedWriter bw = new BufferedWriter(w);
			try {
				long lineIndex = 0;
				String line = null;
				while ((line = br.readLine()) != null) {
					if (lineIndex > 0) {
						bw.newLine();
					}
					bw.write(line);
					bw.flush();
					lineIndex++;
				}
			} finally {
				if (closeReader) {
					close(br);
				}
				if (closeWriter) {
					close(bw);
				}
			}
		}
	}

	/**
	 * <p>方法名：textReader</p>
	 * <p>描述：读取文本流，并返回字符串</p>
	 * @param r 读入流
	 * @return 文本字符串
	 * @throws Exception
	 */
	public static String textReader(InputStreamReader r) throws IOException {
		StringBuffer text = new StringBuffer();
		if (ValidateCommons.isNotEmpty(r)) {
			BufferedReader br = new BufferedReader(r);
			try {
				long lineIndex = 0;
				String line = null;
				while ((line = br.readLine()) != null) {
					if (lineIndex > 0) {
						text.append(StringCommons.NEW_LINE);
					}
					text.append(line);
					lineIndex++;
				}
			} finally {
				close(br);
			}
		}
		return text.toString();
	}

	
	/**
	 * <p>方法名：close</p>
	 * <p>描述：关闭流</p>
	 * @param stream 流
	 * @throws IOException
	 */
	public static void close(Closeable stream) throws IOException {
		if (ValidateCommons.isNotEmpty(stream)) {
			stream.close();
		}
	}

	/**
	 * <p>方法名：closePure</p>
	 * <p>描述：关闭流并处理关闭产生的异常</p>
	 * @param stream 流
	 */
	public static void closePure(Closeable stream) {
		if (ValidateCommons.isNotEmpty(stream)) {
			try {
				stream.close();
			} catch (IOException e) {
				Logger.error(StreamCommons.class, "关闭 IO 异常", e);
			}
		}
	}

}
